<!--
 * @Author       : 方远 15668450208@163.com
 * @Date         : 2024-04-09 16:24:16
 * @LastEditors  : 方远 15668450208@163.com
 * @LastEditTime : 2024-08-21 20:08:24
 * @FilePath     : \zhlx-autoform-ui\src\components\form-designer\form-widget\field-widget\date-widget.vue
 * @Description  : 介绍文件的作用
 * 
 * Copyright (c) 2024 by zhlx - 15668450208@163.com, All Rights Reserved. 
-->
<template>
  <form-item-wrapper :designer="designer" :field="field" :rules="rules" :design-state="designState"
                     :parent-widget="parentWidget" :parent-list="parentList" :index-of-parent-list="indexOfParentList"
                     :sub-form-row-index="subFormRowIndex" :sub-form-col-index="subFormColIndex" :sub-form-row-id="subFormRowId">
    <div :class="[!!field.options.autoFullWidth ? 'auto-full-width' : '', isReadMode ? 'readonly-mode-date' : '']" v-show="!isReadMode">
      <el-date-picker ref="fieldEditor" :type="field.options.type" v-model="dateFidleModel"
                      :class="[!!field.options.autoFullWidth ? 'auto-full-width' : '']"
                      :readonly="field.options.readonly || field.options.disabled || field.options?.isAllowEditSelectorField == '2'" :disabled="field.options.disabled"
                      :clearable="field.options.clearable" :editable="field.options.editable"
                      :format="field.options.format" :value-format="field.options.valueFormat" :time-format="field.options.format.split(' ')[1]"
                      :placeholder="field.options.placeholder || i18nt('render.hint.datePlaceholder')"
                      :disabled-date="date => disabledDate(date, field.options.limitStartDate, field.options.limitEndDate)"
                      @focus="handleFocusCustomEvent" @blur="handleBlurCustomEvent"
                      @change="onFieldChangeEvent">
      </el-date-picker>
    </div>
    <template v-if="isReadMode">
      <span class="readonly-mode-field">{{formatDateFidleModel}}</span>
    </template>
  </form-item-wrapper>
</template>


<script>
  import FormItemWrapper from './form-item-wrapper'
  import emitter from '@/utils/emitter'
  import i18n, {translate} from "@/utils/i18n";
  import fieldMixin from "@/components/form-designer/form-widget/field-widget/fieldMixin";
  import { isJSON } from "@/utils/util"
  import dayjs from "dayjs";

  export default {
    name: "date-widget",
    componentName: 'FieldWidget',  //必须固定为FieldWidget，用于接收父级组件的broadcast事件
    mixins: [emitter, fieldMixin, i18n],
    props: {
      field: Object,
      parentWidget: Object,
      parentList: Array,
      indexOfParentList: Number,
      designer: Object,

      designState: {
        type: Boolean,
        default: false
      },

      subFormRowIndex: { /* 子表单组件行索引，从0开始计数 */
        type: Number,
        default: -1
      },
      subFormColIndex: { /* 子表单组件列索引，从0开始计数 */
        type: Number,
        default: -1
      },
      subFormRowId: { /* 子表单组件行Id，唯一id且不可变 */
        type: String,
        default: ''
      },

    },
    components: {
      FormItemWrapper,
    },
    data() {
      return {
        oldFieldValue: null, //field组件change之前的值
        fieldModel: null,
        rules: [],
        isRefresh: false,
      }
    },
    computed: {
      dateFidleModel: {
        get() {
          if (this.fieldModel?.toString().replace(/[^0-9]/g, "").length == 4) {
            return this.fieldModel
          }
          return isJSON(this.fieldModel) && typeof JSON.parse(this.fieldModel) === "number" ? this.fieldModel * 1 : this.fieldModel
        },
        set(value) {
          this.fieldModel = value
        },
      },
      formatDateFidleModel() {
        if (this.dateFidleModel) {
          let formatDate = this.dateFidleModel
          if (typeof this.dateFidleModel != "number") {
            formatDate = this.dateFidleModel.replace(/年|月/g, '-').replace(/时|分/g, ':').replace(/日|秒/g, '')
          }
          return dayjs(formatDate).format(this.field.options.format)
        } else {
          return this.dateFidleModel
        }
      },
    },
    watch: {
      // 'field.options.readonly': {
      //   deep: true,
      //   handler() {
      //     this.getDateInfo()
      //   }
      // }
      isRefresh: {
        handler() {
          this.getDateInfo()
        }
      },
      formModel: {
        handler(val) {
          let limitStart = val[this.field.options.limitStartWidgetName]
          let limitEnd = val[this.field.options.limitEndWidgetName]
          if (limitStart) {
            if (isJSON(limitStart) && typeof JSON.parse(limitStart) === "number") {
              limitStart *= 1
            }
            this.field.options.limitStartDate = dayjs(limitStart).format("YYYY-MM-DD")
          } else if (limitEnd) {
            if (isJSON(limitEnd) && typeof JSON.parse(limitEnd) === "number") {
              limitEnd *= 1
            }
            this.field.options.limitEndDate = dayjs(limitEnd).format("YYYY-MM-DD")
          }
        },
        deep: true,
        immediate: true,
      }
    },
    beforeCreate() {
      /* 这里不能访问方法和属性！！ */
    },

    created() {
      /* 注意：子组件mounted在父组件created之后、父组件mounted之前触发，故子组件mounted需要用到的prop
         需要在父组件created中初始化！！ */
      this.registerToRefList()
      this.initFieldModel()
      this.initEventHandler()
      this.buildFieldRules()

      this.handleOnCreated()
    },

    mounted() {
      this.handleOnMounted()
      this.setCurrentDateLimit()
      // setTimeout(() => {
      //   this.getDateInfo()
      // }, 1000);
    },

    beforeUnmount() {
      this.unregisterFromRefList()
    },

    methods: {
      /**
       * 获取日期信息
       * 只读：
       *  1.有值 展示值
       *  2.无值 展示空字符串
       * 编辑：
       *  1.有值 展示值
       *  2.无值 且开启当前日期 展示当前日期
       */
      getDateInfo() {
        if (!this.designState) {
          if (!this.field.options.readonly) {
            // 编辑
            if (!this.field.options.defaultValue) {
              if (this.field.options.currentDate) {
                let currentDate = this.formatCurrentDate(this.field.options.valueFormat)
                this.fieldModel = currentDate
                this.setDefaultValue(this.fieldModel)
                this.syncUpdateFormModel(currentDate);
                this.dispatch('VFormRender', 'fieldValidation', [this.getPropName()])
                this.handleChangeEvent(currentDate)
              }
            }
          }
        }
      },
      /**
       * 格式化当前日期
       * @param format 日期格式，支持YYYY、MM、DD、HH、mm、ss、M、D、ZH、H、m、s
       * @returns 格式化后的日期字符串
       * @throws 当格式字符串包含不支持的部分时，抛出异常
       */
      formatCurrentDate(format) {
        let date = new Date();
        function padZero(num, size) {
          let s = num.toString();
          while (s.length < size) {
            s = '0' + s;
          }
          return s;
        }
        // 格式化函数
        function formatPart(part) {
          switch (part) {
            case 'YYYY':
              return date.getFullYear();
            case 'MM':
              return padZero(date.getMonth() + 1, 2);
            case 'DD':
              return padZero(date.getDate(), 2);
            case 'HH':
              return padZero(date.getHours(), 2);
            case 'mm':
              return padZero(date.getMinutes(), 2);
            case 'ss':
              return padZero(date.getSeconds(), 2);
            case 'M':
              return date.getMonth() + 1; // 不补零
            case 'D':
              return date.getDate(); // 不补零
            case 'ZH':
              return '年';
            case 'H':
              return '时';
            case 'm':
              return '分';
            case 's':
              return '秒';
            case 'x':
              date.setSeconds(0);
              date.setMilliseconds(0);
              return date.getTime();
            default:
              throw new Error(`Unsupported format part: ${part}`);
          }
        }
        // 将格式字符串转换为日期
        return format.replace(/YYYY|MM|DD|HH|mm|ss|M|D|ZH|H|m|s|x/g, formatPart);
      },
      /**
       * 日期选择器 设置可选范围
       * @param {*} date date-picker的每一项
       * @param {*} limitStartDate 限制开始日期
       * @param {*} limitEndDate 限制结束日期
       */
      disabledDate(date, limitStartDate, limitEndDate) {
        return date.setHours(0, 0, 0, 0) < (new Date(limitStartDate).setHours(0, 0, 0, 0)) || date.setHours(0, 0, 0, 0) > new Date(limitEndDate).setHours(0, 0, 0, 0)
      },
      /**
       * 设置当前日期限制
       */
      setCurrentDateLimit() {
        if (this.field.options.limitStartOptions == "currendDate") {
          this.field.options.limitStartDate = dayjs(new Date()).format("YYYY-MM-DD")
        } else if (this.field.options.limitEndOptions == "currendDate") {
          this.field.options.limitEndDate = dayjs(new Date()).format("YYYY-MM-DD")
        }
      },
    }
  }
</script>

<style lang="scss" scoped>
  @import "../../../../styles/global.scss"; /* form-item-wrapper已引入，还需要重复引入吗？ */

  .auto-full-width {
    width: 100%;

    :deep(.el-date-editor) {
      width: 100% !important;
    }
  }

  .readonly-mode-date {
    :deep(.el-date-editor) {
      display: none;
    }
  }

</style>
